﻿using System;
using System.Collections.Generic;
using Medianamik.Core.Configuration;
using Medianamik.Core.DAL;
using System.Configuration;
using Medianamik.Core.Urls;
using Medianamik.Core.Logging;
using Medianamik.Core.Interfaces;

namespace Medianamik.Core
{
    public class ObjectFactory<T>
    {
        private static readonly MedianamikConfigSection MedianamikConfigSection =
            (MedianamikConfigSection)ConfigurationManager
            .GetSection(ConfigurationSectionName.MEDIANAMIK);

        private static readonly Dictionary<Type, Delegate> Dico = new Dictionary<Type, Delegate>
        {
            { typeof(ILogger), new Func<string,ILogger>(GetLogger)},
            { typeof(IUrlDictionary), new Func<IUrlDictionary>(GetUrlDictionaryAsSingleton) },
            { typeof(IUrlDictionaryProcess), new Func<IUrlDictionaryProcess>(GetDictionnaryProcess) },
            { typeof(IDALProvider ), new Func<IDALProvider>(GetDALProvider) },
            { typeof(ISyndicationNodeDictionary), new Func<ISyndicationNodeDictionary>( GetSyndicationDictionary)}
        };

        public T Get(params object[] pParams)
        {
            try
            {
                return (T)Dico[typeof(T)].DynamicInvoke(pParams);
            }
            catch (KeyNotFoundException exc)
            {
                throw new CoreException("Unknown type", exc);
            }
        }

        private static ILogger GetLogger(string pLoggerName)
        {
            return new NLogLogger(pLoggerName);
        }

        private static IDALProvider GetDALProvider()
        {
            //// Verify that the a NodeInstanceProvider line exists in the web.config.
            if (MedianamikConfigSection.DALProvider.Length == 0)
            {
                throw new Exception("Data Access Layer Provider name not defined in Medianamik section of web.config.");
            }

            try
            {
                return new ObjectBuilder(MedianamikConfigSection.DALProvider).GetInstance<IDALProvider>();
            }
            catch (Exception excep)
            {
                throw new Exception("Error instantiating the DALProvider " + MedianamikConfigSection.DALProvider + ". ", excep);
            }
        }

        private static IUrlDictionary GetUrlDictionaryAsSingleton()
        {
            //var urlDictionary = UrlDictionary.Instance;
            var urlDictionary = UrlFastDictionary.Instance;

            if (!urlDictionary.Initialized)
                urlDictionary.Initialize(null, new PathSegmentFormater(), null);

            return urlDictionary;
        }

        public static IUrlDictionaryProcess GetDictionnaryProcess()
        {
            return new UrlDictionaryProcess();
        }

        private static ISyndicationNodeDictionary GetSyndicationDictionary()
        {
            throw new NotImplementedException();
            //return CacheManager.Instance.Get< ISyndicationNodeDictionary>("ISyndicationNodeDictionary_AppInstance"
            //     , System.Web.Caching.Cache.NoAbsoluteExpiration 
            //     , TimeSpan.FromHours(1)
            //     , default(CacheDependency)
            //     , CacheItemPriority.NotRemovable
            //     , _createSyndicationDictionaryDelegate);

        }
    }
}
